<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Typing, domain of definition, and exceptions
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora016.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora018.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Typing, domain of definition, and exceptions</H2>
<A NAME="@concepts88"></A>
<A NAME="sec-exceptions"></A>
The inferred type of a function corresponds to a subset of its domain of
definition. Just because a function takes a parameter of type <I>int</I>
doesn't mean it will know how to compute a value for all integers passed as
parameters. In general this problem is dealt with using Objective CAML's
exception mechanism. Raising an exception results in a computational
interruption which can be intercepted and handled by the program. For this
to happen program execution must have registered an exception handler
before the computation of the expression which raises this exception.<BR>
<BR>
<A NAME="toc24"></A>
<H3> Partial functions and exceptions</H3>
<A NAME="@concepts89"></A>
The domain of definition of a function corresponds to the set of values on
which the function carries out its computation. There are many
mathematical functions which are partial; we might mention division or
taking the natural log. This problem also arises for functions which
manipulate more complex data structures. Indeed, what is the result of
computing the first element of an empty list? In the same way, evaluation
of the <TT>factorial</TT> function on a negative integer can lead to an
infinite recursion.<BR>
<BR>
Several exceptional situations may arise during execution of a program, for
example an attempt to divide by zero. Trying to divide a number by zero
will provoke at best a program halt, at worst an inconsistent machine
state. The <EM>safety</EM> of a programming language comes from the
guarantee that such a situation will not arise for these particular cases.
Exceptions are a way of responding to them.<BR>
<BR>
Division of <CODE>1</CODE> by <CODE>0</CODE> will cause a specific
exception to be raised:


<PRE><BR># <CODE>1</CODE><CODE>/</CODE><CODE>0</CODE>;;<BR><CODE>Uncaught exception: Division_by_zero</CODE><BR>

</PRE>

The message <CODE> Uncaught exception: Division_by_zero </CODE> indicates
on the one hand that the <TT>Division_by_zero</TT> exception has been
raised, and on the other hand that it has not been handled. This exception
is among the core declarations of the language.<BR>
<BR>
Often, the type of a function does not correspond to its domain of
definition when a pattern-matching is not exhaustive, that is, when it does
not match all the cases of a given expression. To prevent such an error,
Objective CAML prints a message in such a case.


<PRE><BR># <B>let</B><CODE> </CODE>head<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE>h::t<CODE> </CODE>-&gt;<CODE> </CODE>h<CODE> </CODE>;;<BR><CODE>Characters 14-36:</CODE><BR><CODE>Warning: this pattern-matching is not exhaustive.</CODE><BR><CODE>Here is an example of a value that is not matched:</CODE><BR><CODE>[]</CODE><BR><CODE>val head : 'a list -&gt; 'a = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
If the programmer nevertheless keeps the incomplete definition, Objective CAML
will use the exception mechanism in the case of an erroneous call to the
partial function:


<PRE><BR># head<CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>Uncaught exception: Match_failure("", 14, 36)</CODE><BR>

</PRE>
<BR>
<BR>
Finally, we have already met with another predefined exception:
<TT>Failure</TT>. It takes an argument of type <I>string</I>. One can
raise this exception using the function <TT>failwith</TT>.
<A NAME="@fonctions90"></A>
We can use it in this way to complete
the definition of our <TT>head</TT>:


<PRE><BR># <B>let</B><CODE> </CODE>head<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"Empty list"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>h::t<CODE> </CODE>-&gt;<CODE> </CODE>h;;<BR><CODE>val head : 'a list -&gt; 'a = &lt;fun&gt;</CODE><BR># head<CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>Uncaught exception: Failure("Empty list")</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc25"></A>
<H3> Definition of an exception</H3>
<A NAME="@concepts90"></A><A NAME="@concepts91"></A>
<A NAME="@fonctions91"></A>
<A NAME="@fonctions92"></A>
In Objective CAML, exceptions belong to a predefined type <I>exn</I>. This type
is very special since it is an <EM>extensible</EM> sum type: the set of values
of the type can be extended by declaring new
constructors<A NAME="text11" HREF="book-ora023.html#note11"><SUP><FONT SIZE=2>9</FONT></SUP></A>. This detail lets users define their own exceptions by
adding new constructors to the type <I>exn</I>.<BR>
<BR>
The syntax of an exception declaration is as follows:


<H3> Syntax </H3> <HR>


 <B>exception</B> <I>Name</I> <B>;;</B>



<HR>


or 


<H3> Syntax </H3> <HR>


 <B>exception</B> <I>Name</I> <B>of</B> <I>t</I> <B>;;</B>



<HR>


Here are some examples of exception declarations:


<PRE><BR># <B>exception</B><CODE> </CODE>MY_EXN;;<BR><CODE>exception MY_EXN</CODE><BR># MY_EXN;;<BR><CODE>- : exn = MY_EXN</CODE><BR># <B>exception</B><CODE> </CODE>Depth<CODE> </CODE><B>of</B><CODE> </CODE>int;;<BR><CODE>exception Depth of int</CODE><BR># Depth<CODE> </CODE><CODE>4</CODE>;;<BR><CODE>- : exn = Depth(4)</CODE><BR>

</PRE>

Thus an exception is a full-fledged language value.<BR>
<BR>


<H3> Warning </H3> <HR>

The names of exceptions are constructors. So they necessarily begin with
a capital letter.


<HR>




<PRE><BR># <B>exception</B><CODE> </CODE>lowercase<CODE> </CODE>;;<BR><CODE>Characters 11-20:</CODE><BR><CODE>Syntax error</CODE><BR>

</PRE>
<BR>
<BR>


<H3> Warning </H3> <HR>

Exceptions are monomorphic: they do not have type parameters in the
declaration of the type of their argument.


<HR>




<PRE><BR># <B>exception</B><CODE> </CODE>Value<CODE> </CODE><B>of</B><CODE> </CODE><I>'a</I><CODE> </CODE>;;<BR><CODE>Characters 20-22:</CODE><BR><CODE>Unbound type parameter 'a</CODE><BR>

</PRE>

A polymorphic exception would permit the definition of functions with an
arbitrary return type as we will see further on, page
<A HREF="book-ora018.html#sec-retourpoly">??</A>.<BR>
<BR>
<A NAME="toc26"></A>
<H3> Raising an exception</H3>
<A NAME="@concepts92"></A>
<A NAME="@fonctions93"></A>
<A NAME="sub-raise"></A>
The function <TT>raise</TT> is a primitive function of the language. It
takes an exception as an argument and has a completely polymorphic return
type.


<PRE><BR># raise<CODE> </CODE>;;<BR><CODE>- : exn -&gt; 'a = &lt;fun&gt;</CODE><BR># raise<CODE> </CODE>MY_EXN;;<BR><CODE>Uncaught exception: MY_EXN</CODE><BR># <CODE>1</CODE><CODE>+</CODE><TT>(</TT>raise<CODE> </CODE>MY_EXN<TT>)</TT>;;<BR><CODE>Uncaught exception: MY_EXN</CODE><BR># raise<CODE> </CODE><TT>(</TT>Depth<CODE> </CODE><CODE>4</CODE><TT>)</TT>;;<BR><CODE>Uncaught exception: Depth(4)</CODE><BR>

</PRE>

It is not possible to write the function <TT>raise</TT> in Objective CAML. It
must be predefined. <BR>
<BR>
<A NAME="toc27"></A>
<H3> Exception handling</H3>
The whole point of raising exceptions lies in the ability to handle them and
to direct the sequence of computation according to the value of the
exception raised. The order of evaluation of an expression thus becomes
important for determining which exception is raised. We are leaving the
purely functional context, and entering a domain where the order of
evaluation of arguments can change the result of a computation, as will be
discussed in the following chapter (see page
<A HREF="book-ora029.html#sec-ordre">??</A>).<BR>
<BR>
The following syntactic construct, which computes the value of an expression, permits
the handling of an exception raised during this computation:
<A NAME="@concepts93"></A>
<A NAME="@fonctions94"></A>
<A NAME="@fonctions95"></A>


<H3> Syntax </H3> <HR>


<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><B>try</B> <I>expr</I> <B>with</B></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>|</B> <I>p</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB>  -&gt; <I>expr</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>:</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>|</B> <I>p</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB>  -&gt; <I>expr</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB></TD>
</TR></TABLE>



<HR>


If the evaluation of <I>expr</I> does not raise any exception, then the
result is that of the evaluation of <I>expr</I>. Otherwise, the value of
the exception which was raised is pattern-matched; the value of the
expression corresponding to the first matching pattern is returned. If
none of the patterns corresponds to the value of the exception then the
latter is propagated up to the next outer 
<B>try-with</B> entered during the execution of the program.
Thus pattern matching an exception is always considered to be exhaustive.
Implicitly, the last pattern is <EM>|</EM><EM> e -&gt; raise e</EM>.
If no matching exception handler is found in the program, the system itself takes
charge of intercepting the exception and terminates the program while
printing an error message.<BR>
<BR>
One must not confuse <EM>computing</EM> an exception (that is, a value of
type <I>exn</I>) with <EM>raising</EM> an exception which causes
computation to be interrupted. An exception being a value like others, it
can be returned as the result of a function.


<PRE><BR># <B>let</B><CODE> </CODE>return<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Failure<CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val return : string -&gt; exn = &lt;fun&gt;</CODE><BR># return<CODE> </CODE><CODE>"test"</CODE><CODE> </CODE>;;<BR><CODE>- : exn = Failure("test")</CODE><BR># <B>let</B><CODE> </CODE>my_raise<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>raise<CODE> </CODE><TT>(</TT>Failure<CODE> </CODE>x<TT>)</TT><CODE> </CODE>;;<BR><CODE>val my_raise : string -&gt; 'a = &lt;fun&gt;</CODE><BR># my_raise<CODE> </CODE><CODE>"test"</CODE><CODE> </CODE>;;<BR><CODE>Uncaught exception: Failure("test")</CODE><BR>

</PRE>

We note that applying <TT>my_raise</TT> does not return any value while
applying <TT>return</TT> returns one of type <I>exn</I>.<BR>
<BR>

<H4> Computing with exceptions</H4>
Beyond their use for handling exceptional values, exceptions also support a
specific programming style and can be the source of optimizations. The following
example finds the product of all the elements of a list of integers. We
use an exception to interrupt traversal of the list and return the value
<EM>0</EM> when we encounter it.


<PRE><BR># <B>exception</B><CODE> </CODE>Found_zero<CODE> </CODE>;;<BR><CODE>exception Found_zero</CODE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>mult_rec<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>match</B><CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>[]<CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>::<CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE>raise<CODE> </CODE>Found_zero<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>n<CODE> </CODE>::<CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>n<CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>(</TT>mult_rec<CODE> </CODE>x<TT>)</TT><CODE> </CODE>;;<BR><CODE>val mult_rec : int list -&gt; int = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>mult_list<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>try</B><CODE> </CODE>mult_rec<CODE> </CODE>l<CODE> </CODE><B>with</B><CODE> </CODE>Found_zero<CODE> </CODE>-&gt;<CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<CODE> </CODE><BR><CODE>val mult_list : int list -&gt; int = &lt;fun&gt;</CODE><BR># mult_list<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>0</CODE>;<CODE>5</CODE>;<CODE>6</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int = 0</CODE><BR>

</PRE>

So all the computations standing by, namely the multiplications by <I>n</I>
which follow each of the recursive calls, are abandoned. After
encountering <B>raise</B>, computation resumes from the pattern-matching
under <B>with</B>.<BR>
<BR>
<HR>
<A HREF="book-ora016.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora018.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
